#pragma once

#include <iostream>
#include <functional>
#include <string>
#include <memory>
#include "Socket.hpp"
#include "InetAddr.hpp"

using namespace Socket_ns;

class TCPServer;
// 线程数据的封装
class ThreadData
{
public:
    ThreadData(socket_sptr sockfd, const InetAddr& clientAddr, TCPServer* self)
        : _sockfd(sockfd), _clientAddr(clientAddr), _self(self)
    {}

public:
    socket_sptr _sockfd;
    InetAddr _clientAddr;
    TCPServer* _self;
};

// 服务器进行服务的函数类型，由外部传入函数对象完成
using io_service_t = std::function<void (Socket_ns::socket_sptr, const InetAddr&)>;

class TCPServer
{
private:
    static void* HandlerSock(void* arg)
    {
        // 线程自己分离
        pthread_detach(pthread_self());

        ThreadData* td = static_cast<ThreadData*>(arg);
        td->_self->_service(td->_sockfd, td->_clientAddr);

        delete td;
        return nullptr;
    }
public:
    TCPServer(int port, io_service_t service)
        : _serverAddr("0", port),
          _listenSock(std::make_unique<TCPSocket>()),
          _service(service),
          _isRunning(false)
    {
        _listenSock->BuildListenSocket(_serverAddr);
    }

    void Loop()
    {
        while(true)
        {
            InetAddr clientAddr;
            socket_sptr fd = _listenSock->Accepter(&clientAddr);
            if(nullptr == fd) continue;

            // 创建线程执行任务
            pthread_t t;
            ThreadData* td = new ThreadData(fd, clientAddr, this);
            pthread_create(&t, nullptr, HandlerSock, td);
        }
    }

    ~TCPServer()
    {}
private:
    bool _isRunning;
    InetAddr _serverAddr;  
    std::unique_ptr<Socket> _listenSock;
    io_service_t _service;
};